<script setup lang="ts">
defineOptions({
  name: "Announcement"
});

import { ref, onMounted, nextTick } from "vue";
import {
  ElButton,
  ElInput,
  ElTable,
  ElTableColumn,
  ElPagination,
  ElTag,
  ElMessage,
  ElMessageBox,
  ElDialog,
  ElSelect,
  ElOption,
  ElSwitch,
  ElForm,
  ElFormItem,
  ElLoading
} from "element-plus";
import {
  queryNotices,
  deleteNotices,
  publishNotice,
  addNotice,
  updateNotice
} from "../../../api/notice";
import { findAllCells } from "../../../api/cell";
import type {
  NoticeBase,
  NoticeQueryDto,
  BaseDeleteDto,
  InsertNoticeDto
} from "../../../api/notice";
import type { Cell } from "../../../api/cell";

// 搜索关键词
const searchKeyword = ref("");

// 分页数据
const currentPage = ref(1);
const pageSize = ref(10);
const totalCount = ref(0); // 总条数
const loading = ref(false); // 加载状态

// 公告数据列表
const announcementData = ref<NoticeBase[]>([]);

// 对话框状态
const dialogVisible = ref(false);
// 编辑状态标识
const isEdit = ref(false);
// 表单数据
interface FormDataType extends InsertNoticeDto {
  id?: number;
}
const formData = ref<FormDataType>({
  noticeName: "",
  noticeType: "",
  cellId: undefined, // 不设置默认值
  content: "",
  isTop: 0,
  status: "",
  publisher: ""
});
// 表单校验规则，使用正确的Element Plus表单验证规则类型
const rules: Record<string, any[]> = {
  noticeName: [{ required: true, message: "请输入公告标题", trigger: "blur" }],
  noticeType: [
    { required: true, message: "请选择公告分类", trigger: "change" }
  ],
  cellId: [
    { required: true, message: "请选择小区", trigger: "change" },
    { type: "number", min: 1, message: "请选择有效的小区", trigger: "change" }
  ],
  content: [{ required: true, message: "请输入公告内容", trigger: "blur" }]
};
// 表单引用
const formRef = ref<InstanceType<typeof ElForm>>();
// 查询条件
const queryParams = ref<NoticeQueryDto>({});

// 公告分类选项
const noticeTypes = ref([
  { label: "通知", value: "通知" },
  { label: "公告", value: "公告" },
  { label: "提醒", value: "提醒" },
  { label: "紧急", value: "紧急" }
]);

// 小区数据类型定义
interface CommunityOption {
  label: string;
  value: number;
}

// 小区选项
const communities = ref<CommunityOption[]>([]);

// 加载小区数据
const loadCellData = async () => {
  try {
    const response = await findAllCells();
    if (response.code === 0 || response.code === 200) {
      const cells = response.data || [];
      // 转换小区数据格式，不包含"全部"选项
      const newCommunities = cells.map((cell: Cell) => ({
        label: cell.name,
        value: cell.id
      }));
      communities.value = newCommunities;
    }
  } catch (error) {
    console.error("获取小区数据失败:", error);
  }
};

// 加载公告数据
const loadNoticeData = async () => {
  loading.value = true;
  try {
    const queryData: NoticeQueryDto = {
      ...queryParams.value,
      pageNum: currentPage.value,
      pageSize: pageSize.value
    };

    const response = await queryNotices(queryData);

    // 后端返回的code是0表示成功，需要适配这种格式
    if (response.code === 0 || response.code === 200) {
      // 适配后端实际返回格式
      if (Array.isArray(response.data)) {
        // 如果直接返回数组
        announcementData.value = response.data;
        totalCount.value = response.data.length;
      } else if (response.data && response.data.records) {
        // 如果返回分页对象
        announcementData.value = response.data.records || [];
        totalCount.value = response.data.total || 0;
      } else {
        announcementData.value = [];
        totalCount.value = 0;
      }
    } else {
      ElMessage.error(response.message || "获取公告数据失败");
    }
  } catch (error) {
    console.error("获取公告数据失败:", error);
    ElMessage.error("获取公告数据失败");
  } finally {
    loading.value = false;
  }
};

// 根据小区ID查找小区名称
const findCellNameById = (cellId: number): string => {
  const community = communities.value.find(item => item.value === cellId);
  return community ? community.label : `${cellId}`;
};

// 搜索方法
const handleSearch = () => {
  queryParams.value.noticeName = searchKeyword.value;
  currentPage.value = 1; // 搜索时重置到第一页
  loadNoticeData();
};

// 发布公告
const handlePublish = () => {
  // 重置表单
  if (formRef.value) {
    formRef.value.resetFields();
  }
  // 清空表单数据
  Object.assign(formData.value, {
    noticeName: "",
    noticeType: "",
    cellId: undefined,
    content: "",
    isTop: 0,
    status: "",
    publisher: ""
  });
  // 显示对话框
  dialogVisible.value = true;
};

// 实际发布公告
const doPublish = async () => {
  if (!formRef.value) return;

  try {
    await formRef.value.validate();

    // 显示全局加载状态
    ElLoading.service({
      lock: true,
      text: "正在发布...",
      background: "rgba(0, 0, 0, 0.7)"
    });

    // 确保所有必填字段都有值
    const submitData = {
      noticeName: formData.value.noticeName,
      noticeType: formData.value.noticeType,
      cellId: formData.value.cellId,
      content: formData.value.content,
      isTop: formData.value.isTop || 0,
      status: "已发布",
      publisher: "admin" // 这里应该从用户信息中获取
    };

    console.log("提交发布数据:", submitData);
    let response;
    
    // 根据是否处于编辑状态选择API
    if (isEdit.value && formData.value.id) {
      // 编辑模式：调用更新API
      response = await updateNotice({...submitData, id: formData.value.id});
    } else {
      // 新增模式：调用添加API
      response = await addNotice(submitData as InsertNoticeDto);
    }

    if (response.code === 0 || response.code === 200) {
      ElMessage.success("发布成功");
      dialogVisible.value = false;
      isEdit.value = false; // 重置编辑状态
      await loadNoticeData(); // 重新加载数据
    } else {
      ElMessage.error(response.message || "发布失败");
    }
  } catch (error: any) {
    console.error("发布公告失败:", error);
    // 如果不是表单校验错误，则显示错误消息
    if (!error?.message?.includes("cancel")) {
      ElMessage.error("发布失败");
    }
  } finally {
    // 关闭加载状态
    ElLoading.service().close();
  }
};

// 保存草稿
const saveDraft = async () => {
  if (!formRef.value) return;

  try {
    await formRef.value.validate();

    // 显示全局加载状态
    ElLoading.service({
      lock: true,
      text: "正在保存...",
      background: "rgba(0, 0, 0, 0.7)"
    });

    // 确保所有必填字段都有值
    const submitData = {
      noticeName: formData.value.noticeName,
      noticeType: formData.value.noticeType,
      cellId: formData.value.cellId,
      content: formData.value.content,
      isTop: formData.value.isTop || 0,
      status: "草稿",
      publisher: "admin" // 这里应该从用户信息中获取
    };

    console.log("保存草稿数据:", submitData);
    let response;
    
    // 根据是否处于编辑状态选择API
    if (isEdit.value && formData.value.id) {
      // 编辑模式：调用更新API
      response = await updateNotice({...submitData, id: formData.value.id});
    } else {
      // 新增模式：调用添加API
      response = await addNotice(submitData as InsertNoticeDto);
    }

    if (response.code === 0 || response.code === 200) {
      ElMessage.success("保存成功");
      dialogVisible.value = false;
      isEdit.value = false; // 重置编辑状态
      await loadNoticeData(); // 重新加载数据
    } else {
      ElMessage.error(response.message || "保存失败");
    }
  } catch (error: any) {
    console.error("保存公告失败:", error);
    // 如果不是表单校验错误，则显示错误消息
    if (!error?.message?.includes("cancel")) {
      ElMessage.error("保存失败");
    }
  } finally {
    // 关闭加载状态
    ElLoading.service().close();
  }
};

// 关闭对话框
const closeDialog = () => {
  if (formRef.value) {
    formRef.value.resetFields();
  }
  // 重置表单数据
  formData.value = {
    noticeName: "",
    noticeType: "",
    cellId: undefined,
    content: "",
    isTop: 0,
    status: "",
    publisher: ""
  };
  dialogVisible.value = false;
};

// 添加公告分类
const addNoticeType = () => {
  ElMessageBox.prompt("请输入新的临时公告分类", "添加公告分类", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    inputPattern: /^\S+$/,
    inputErrorMessage: "分类名称不能为空或包含空格"
  })
    .then(({ value }) => {
      // 检查是否已存在
      const exists = noticeTypes.value.some(item => item.value === value);
      if (exists) {
        ElMessage.warning("该分类已存在");
        return;
      }

      // 添加新分类
      noticeTypes.value.push({
        label: value,
        value: value
      });
      ElMessage.success("添加成功");
    })
    .catch(() => {
      // 取消操作
    });
};

// 编辑公告
const handleEdit = async (row: NoticeBase) => {
  // 确保小区数据已加载
  if (communities.value.length === 0) {
    await loadCellData();
  }

  // 设置编辑状态
  isEdit.value = true;
  
  // 设置表单数据
  formData.value = {
    id: row.id,
    noticeName: row.noticeName,
    noticeType: row.noticeType,
    cellId: row.cellId,
    content: row.content,
    isTop: row.isTop || 0,
    status: row.status,
    publisher: row.publisher
  };

  console.log("编辑时设置的表单数据:", formData.value);
  dialogVisible.value = true;
};

// 删除公告
const handleDelete = async (row: NoticeBase) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除公告「${row.noticeName}」吗？`,
      "确认删除",
      {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }
    );

    const deleteData: BaseDeleteDto = { ids: [row.id!] };
    const response = await deleteNotices(deleteData);

    // 与其他函数保持一致，同时支持code为0或200的情况
    if (response.code === 0 || response.code === 200) {
      ElMessage.success("删除成功");
      await loadNoticeData(); // 重新加载数据，确保删除后的数据不残留
    } else {
      ElMessage.error(response.message || "删除失败");
    }
  } catch (error: any) {
    if (error.message !== "cancel") {
      console.error("删除公告失败:", error);
      ElMessage.error("删除失败");
    }
  }
};

// 发布公告状态
const handlePublishStatus = async (row: NoticeBase) => {
  try {
    const response = await publishNotice(row.id!);
    // 与loadNoticeData函数保持一致，同时支持code为0或200的情况
    if (response.code === 0 || response.code === 200) {
      ElMessage.success("发布成功");
      await loadNoticeData(); // 重新加载数据
    } else {
      ElMessage.error(response.message || "发布失败");
    }
  } catch (error) {
    console.error("发布公告失败:", error);
    ElMessage.error("发布失败");
  }
};

// 页码变化
const handlePageChange = (val: number) => {
  currentPage.value = val;
  loadNoticeData();
};

// 每页条数变化
const handleSizeChange = (val: number) => {
  pageSize.value = val;
  loadNoticeData();
};

// 跳转到指定页
const handleJumpToPage = (val: number) => {
  if (
    val &&
    !isNaN(val) &&
    val >= 1 &&
    val <= Math.ceil(totalCount.value / pageSize.value)
  ) {
    currentPage.value = parseInt(val.toString());
    loadNoticeData();
  }
};

// 组件挂载时加载数据
onMounted(async () => {
  // 先加载小区数据
  await loadCellData();
  // 再加载公告数据
  await loadNoticeData();
});
</script>

<template>
  <div class="announcement-container">
    <div class="announcement-header">
      <el-button type="primary" @click="handlePublish">+ 发布公告</el-button>
      <div class="search-container">
        <div style="display: flex; gap: 10px; align-items: center;">
          <el-input
            v-model="searchKeyword"
            placeholder="请输入公告名称"
            clearable
            class="search-input"
            @keyup.enter="handleSearch"
            style="flex: 1;"
          />
          <el-button type="primary" @click="handleSearch">搜索</el-button>
        </div>
      </div>
    </div>

    <el-table
      v-loading="loading"
      :data="announcementData"
      style="width: 100%"
      border
    >
      <el-table-column prop="noticeName" label="公告名称" min-width="180">
        <template #default="{ row }">
          <span>{{ row.noticeName }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="noticeType" label="公告分类" min-width="100">
        <template #default="{ row }">
          <span>{{ row.noticeType || "-" }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="cellId" label="关联小区" min-width="120">
          <template #default="{ row }">
            <span>{{ findCellNameById(row.cellId) || "-" }}</span>
          </template>
        </el-table-column>
      <el-table-column prop="updateTime" label="发布时间" min-width="150">
        <template #default="{ row }">
          <span>{{ row.updateTime || "-" }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="status" label="状态" min-width="100">
        <template #default="{ row }">
          <span
            :class="{
              'status-draft': row.status === '草稿',
              'status-unpublished': row.status === '未发布'
            }"
          >
            {{ row.status }}
          </span>
        </template>
      </el-table-column>
      <el-table-column prop="publisher" label="发布人" min-width="100">
        <template #default="{ row }">
          <span>{{ row.publisher || "-" }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="isTop" label="是否置顶" min-width="100">
        <template #default="{ row }">
          <el-tag v-if="row.isTop === 1" size="small" effect="light">是</el-tag>
          <span v-else>否</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" min-width="200" fixed="right">
        <template #default="{ row }">
          <el-button type="primary" link size="small" @click="handleEdit(row)">
            编辑
          </el-button>
          <el-button
            v-if="row.status === '草稿' || row.status === '未发布'"
            type="success"
            link
            size="small"
            @click="handlePublishStatus(row)"
          >
            发布
          </el-button>
          <el-button type="danger" link size="small" @click="handleDelete(row)">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="pagination-container">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50, 100]"
        layout="prev, pager, next, jumper, sizes, total"
        :total="totalCount"
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
        @jump="handleJumpToPage"
      />
    </div>

    <!-- 发布公告对话框 -->
    <el-dialog
      v-model="dialogVisible"
      title="发布公告"
      width="600px"
      :before-close="closeDialog"
      :close-on-click-modal="false"
    >
      <el-form
        ref="formRef"
        :model="formData"
        :rules="rules"
        label-width="100px"
        class="notice-form"
      >
        <el-form-item label="公告标题" prop="noticeName">
          <el-input
            v-model="formData.noticeName"
            placeholder="请输入公告名称"
          />
        </el-form-item>

        <el-form-item label="公告分类" prop="noticeType">
          <el-select v-model="formData.noticeType" placeholder="请选择">
            <el-option
              v-for="item in noticeTypes"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
          <el-button type="text" @click="addNoticeType"
            >+添加公告分类</el-button
          >
        </el-form-item>

        <el-form-item label="关联小区" prop="cellId">
          <el-select
            v-model="formData.cellId"
            placeholder="请选择小区"
            :disabled="!dialogVisible"
          >
            <el-option
              v-for="item in communities"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="公告内容" prop="content">
          <el-input
            v-model="formData.content"
            type="textarea"
            placeholder="请输入"
            :rows="10"
            style="width: 100%"
          />
        </el-form-item>

        <el-form-item label="是否置顶">
          <el-switch
            v-model="formData.isTop"
            :active-value="1"
            :inactive-value="0"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="closeDialog">返回</el-button>
        <el-button type="primary" @click="saveDraft">保存</el-button>
        <el-button type="success" @click="doPublish">发布</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.announcement-container {
  padding: 20px;
}

.announcement-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.search-container {
  width: 400px;
}

.search-input {
  width: 100%;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.notice-form {
  margin-top: 20px;
}

.status-draft {
  color: #909399;
}

.status-unpublished {
  color: #e6a23c;
}
</style>
